﻿// Copyright (c) 2010. Eric Nelson  
// https://code.google.com/p/prompts/
// All rights reserved.
//     
// Redistribution and use in source and binary forms,   
// with or without modification, are permitted provided   
// that the following conditions are met:    
// * Redistributions of source code must retain the   
// above copyright notice, this list of conditions and   
// the following disclaimer.    
// * Redistributions in binary form must reproduce   
// the above copyright notice, this list of conditions   
// and the following disclaimer in the documentation   
// and/or other materials provided with the distribution.    
// * Neither the name of Eric Nelson nor the   
// names of its contributors may be used to endorse   
// or promote products derived from this software   
// without specific prior written permission.    
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND   
// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,   
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF   
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE   
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR   
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,   
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS   
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING   
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   
// SUCH DAMAGE.
// 
//     
// [This is the BSD license, see  
// http://www.opensource.org/licenses/bsd-license.php]  
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Windows;
using Prompts.Prompting.Model;
using Prompts.PromptServiceProxy;
using Prompts.ReportCatalog.Model;

namespace Prompts
{
    public static class ServiceInjector
    {
        public static T Inject<T>() where T : class
        {
            var elements = new BindingElementCollection {new BinaryMessageEncodingBindingElement()};

            var bindingElement =
                new HttpTransportBindingElement
                    {
                        MaxBufferSize = int.MaxValue,
                        MaxReceivedMessageSize = int.MaxValue
                    };
            elements.Add(bindingElement);

            var binding = new CustomBinding(elements);

            if (typeof (T) == typeof (IChildPromptLevelServiceClient))
            {
                var endpoint = GetPromptServiceEndpoint("ChildPromptLevelService");
                return new ChildPromptLevelServiceClient(binding, endpoint) as T;
            }
            if (typeof (T) == typeof (IPromptServiceClient))
            {
                var endpoint = GetPromptServiceEndpoint("PromptService");
                return new PromptServiceClient(binding, endpoint) as T;
            }
            if (typeof (T) == typeof (IPromptSelectionService2Client))
            {
                var endpoint = GetPromptServiceEndpoint("PromptSelectionService");
                return new PromptSelectionServiceClient(binding, endpoint) as T;
            }
            if (typeof (T) == typeof (IReportCatalogServiceClient))
            {
                var endpoint = GetEndpoint("ReportCatalogService", "/Prompts.Service/ReportCatalogService");
                return new ReportCatalogServiceClient(binding, endpoint) as T;
            }

            throw new Exception();
        }

        private static EndpointAddress GetPromptServiceEndpoint(string serviceName)
        {
            const string promptServiceBaseUri = "/Prompts.Service/PromptService";
            return GetEndpoint(serviceName, promptServiceBaseUri);
        }

        private static EndpointAddress GetEndpoint(string serviceName, string serviceUriBase)
        {
            var absoluteServiceUri = string.Format("{0}/{1}.svc", serviceUriBase, serviceName);
            string uri;
            if (Application.Current.Host.Source != null)
            {
                uri = new Uri(Application.Current.Host.Source, absoluteServiceUri).AbsoluteUri;
            }
            else
            {
                throw new Exception(
                    "An excpetion occured while trying to resolve 'Application.Current.Host.Source'");
            }
            return new EndpointAddress(uri);
        }
    }
}